#include "sendcanprotmanager.h"

#include <QDebug>
#include <QStringList>

//SendCANProtManager::SendCANProtManager(QObject *parent) : QObject(parent)
//{
//    // 初始化循环计数器
//}


//加载JSON配置文件
bool SendCANProtManager::loadConfig(const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qWarning() << "无法打开配置文件:" << filePath;
        return false;
    }

    QByteArray data = file.readAll();
    file.close();

    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (doc.isNull()) {
        qWarning() << "配置文件不是有效的JSON格式";
        return false;
    }

    if (!doc.isObject()) {
        qWarning() << "JSON根元素不是对象";
        return false;
    }

    parseConfig(doc.object());
    return true;
}

//获取所有报文名称
QStringList SendCANProtManager::getMessageNames() const
{
    return m_messageConfigs.keys();
}

//生成指定报文的16进制数据
QByteArray SendCANProtManager::generateMessageData(const QString &msgName, const QMap<QString, QVariant> &signalValues)
{
    if (!m_messageConfigs.contains(msgName)) {
        qWarning() << "未知的报文名称:" << msgName;
        return QByteArray();
    }

    MessageConfig msgConfig = m_messageConfigs[msgName];
    QByteArray data(msgConfig.length, 0x00);  // 初始化数据字节数组

    // 1. 设置初始值
    for (const auto &signal : msgConfig.signalL) {
        bool ok;
        quint64 initialValue = signal.initialValue.toULongLong(&ok, 16);
        if (ok) {
            setBits(data, signal, initialValue);
        }
    }

    // 2. 设置用户指定的信号值
    for (const auto &key : signalValues.keys()) {
        if (!msgConfig.signalL.contains(key)) {
            qWarning() << "报文" << msgName << "中不存在信号:" << key;
            continue;
        }

        SignalConfig signal = msgConfig.signalL[key];
        QVariant value = signalValues[key];

        // 转换为物理值
        double physValue = value.toDouble();

        // 检查物理值是否在有效范围内
        if (physValue < signal.physMin || physValue > signal.physMax) {
            qWarning() << "信号" << key << "的值超出范围:" << physValue
                      << "[" << signal.physMin << "," << signal.physMax << "]";
            continue;
        }

        // 转换为总线值并设置
        quint64 rawValue = physicalToRaw(signal, physValue);
        setBits(data, signal, rawValue);
    }

    // 3. 更新循环计数器
    if (msgConfig.signalL.contains("RollingCounter")) {
        SignalConfig counterSignal = msgConfig.signalL["RollingCounter"];
        quint8 counterValue = updateRollingCounter(msgName);
        setBits(data, counterSignal, counterValue);
    }

    // 4. 计算并设置校验和
    if (msgConfig.signalL.contains("CheckSum")) {
        SignalConfig checkSumSignal = msgConfig.signalL["CheckSum"];
        quint8 checkSum = calculateChecksum(data, checkSumSignal);
        setBits(data, checkSumSignal, checkSum);
    }

    return data;
}

//获取指定报文的配置信息
MessageConfig SendCANProtManager::getMessageConfig(const QString &msgName) const
{
    if (m_messageConfigs.contains(msgName)) {
        return m_messageConfigs[msgName];
    }
    return MessageConfig();
}

//解析JSON配置
void SendCANProtManager::parseConfig(const QJsonObject &jsonObject)
{
    m_messageConfigs.clear();

    if (!jsonObject.contains("protocols") || !jsonObject["protocols"].isArray()) {
        qWarning() << "JSON配置中不包含有效的protocols数组";
        return;
    }

    QJsonArray protocolsArray = jsonObject["protocols"].toArray();
    for (const auto &protocolValue : protocolsArray) {
        if (!protocolValue.isObject()) {
            continue;
        }

        QJsonObject protocolObj = protocolValue.toObject();
        MessageConfig msgConfig;

        msgConfig.name = protocolObj["msg_name"].toString();
        msgConfig.type = protocolObj["msg_type"].toString();
        msgConfig.id = protocolObj["msg_id"].toString();
        msgConfig.sendType = protocolObj["msg_send_type"].toString();
        msgConfig.cycleTime = protocolObj["msg_cycle_time"].toInt();
        msgConfig.length = protocolObj["msg_length"].toInt();

        // 解析信号配置
        if (protocolObj.contains("signals") && protocolObj["signals"].isArray()) {
            QJsonArray signalLArray = protocolObj["signals"].toArray();
            for (const auto &signalValue : signalLArray) {
                if (!signalValue.isObject()) {
                    continue;
                }

                QJsonObject signalObj = signalValue.toObject();
                SignalConfig signalConfig;

                signalConfig.name = signalObj["signal_name"].toString();
                signalConfig.description = signalObj["signal_description"].toString();
                signalConfig.byteOrder = signalObj["byte_order"].toString();
                signalConfig.startByte = signalObj["start_byte"].toInt();
                signalConfig.startBit = signalObj["start_bit"].toInt();
                signalConfig.sendType = signalObj["signal_send_type"].toString();
                signalConfig.bitLength = signalObj["bit_length"].toInt();
                signalConfig.dataType = signalObj["data_type"].toString();
                signalConfig.resolution = signalObj["resolution"].toDouble();
                signalConfig.offset = signalObj["offset"].toDouble();
                signalConfig.physMin = signalObj["phys_min"].toDouble();
                signalConfig.physMax = signalObj["phys_max"].toDouble();
                signalConfig.hexMin = signalObj["hex_min"].toString();
                signalConfig.hexMax = signalObj["hex_max"].toString();
                signalConfig.initialValue = signalObj["initial_value"].toString();
                signalConfig.invalidValue = signalObj["invalid_value"].toString();
                signalConfig.inactiveValue = signalObj["inactive_value"].toString();
                signalConfig.unit = signalObj["unit"].toString();
                signalConfig.valueDescription = signalObj["value_description"].toString();

                msgConfig.signalL[signalConfig.name] = signalConfig;
            }
        }

        m_messageConfigs[msgConfig.name] = msgConfig;
        m_rollingCounters[msgConfig.name] = 0;  // 初始化循环计数器
    }

    qInfo() << "PCAN发送报文配置加载成功，共加载" << m_messageConfigs.size() << "个报文配置";
}

//计算校验和
quint8 SendCANProtManager::calculateChecksum(const QByteArray &data, const SignalConfig &checkSumSignal)
{
    // 计算前7个字节的异或校验和
    quint8 checksum = 0;
    for (int i = 0; i < qMin(7, data.size()); ++i) {
        checksum ^= static_cast<quint8>(data[i]);
    }
    return checksum;
}

//更新循环计数器
quint8 SendCANProtManager::updateRollingCounter(const QString &msgName)
{
    if (!m_rollingCounters.contains(msgName)) {
        m_rollingCounters[msgName] = 0;
        return 0;
    }

    quint8 current = m_rollingCounters[msgName];
    current = (current + 1) % 16;  // 0~15循环计数
    m_rollingCounters[msgName] = current;
    return current;
}

//将物理值转换为总线值
quint64 SendCANProtManager::physicalToRaw(const SignalConfig &signal, double physValue)
{
    // 物理值到总线值的转换公式: raw = (phys - offset) / resolution
    double rawDouble = (physValue - signal.offset) / signal.resolution;
    return static_cast<quint64>(qRound(rawDouble));
}

//将值写入字节数组的指定位
void SendCANProtManager::setBits(QByteArray &data, const SignalConfig &signal, quint64 value)
{
    qInfo() << "SendCANProtManager::setBits 设置模式: " << signal.byteOrder;
    // 确保数据长度足够
    if (signal.startByte >= data.size()) {
        qWarning() << "信号" << signal.name << "的起始字节超出数据范围";
        return;
    }

    // 检查值是否超出信号位长度所能表示的范围
    quint64 maxValue = (1ULL << signal.bitLength) - 1;
    if (value > maxValue) {
        qWarning() << "信号" << signal.name << "的值超出位长度范围，将被截断";
        value &= maxValue;
    }

    // 处理Motorola格式 (大端)
    if (signal.byteOrder.contains("Motorola", Qt::CaseInsensitive)) {
        int currentBit = signal.startBit;
        for (int i = 0; i < signal.bitLength; ++i) {
            int byteIndex = currentBit / 8;
            int bitIndex = currentBit % 8;  // Intel格式位顺序是从低到高

            if (byteIndex >= data.size()) {
                qWarning() << "信号" << signal.name << "超出数据字节范围";
                break;
            }

            // 清除当前位并设置新值
            quint8 mask = ~(1 << bitIndex);
            quint8 byte = data[byteIndex] & mask;
            if (value & (1ULL << i)) {
                byte |= (1 << bitIndex);
            }
            data[byteIndex] = byte;

            currentBit++;
        }
    }
    // 处理Intel格式 (小端)
    else if (signal.byteOrder.contains("Intel", Qt::CaseInsensitive)) {
        int currentBit = signal.startBit;
        for (int i = 0; i < signal.bitLength; ++i) {
            int byteIndex = currentBit / 8;
            int bitIndex = 7 - (currentBit % 8);  // Motorola格式位顺序是从高到低

            if (byteIndex >= data.size()) {
                qWarning() << "信号" << signal.name << "超出数据字节范围";
                break;
            }

            // 清除当前位并设置新值
            quint8 mask = ~(1 << bitIndex);
            quint8 byte = data[byteIndex] & mask;
            if (value & (1ULL << (signal.bitLength - 1 - i))) {
                byte |= (1 << bitIndex);
            }
            data[byteIndex] = byte;

            currentBit++;
        }
    }
}
